/*****************************************************************************
*   uart.c:  source file for UART
*		ver 1.0
******************************************************************************/

#include "me32g030.h"
#include "me32g030_uart.h"

extern uint32_t SystemCoreClock;
/*****************************************************************************
Function Name	UART_Open
Function Definition	void UART_Open(UART0_Type *uart, uint32_t baudrate, uint8_t parityoption, uint8_t rxinttriggerlevel);
Function Description	Initial UART 
Input Parameters	*uart : pointer to UART device, UART0/UART1/UART2/UART3
									Baudrate: baudrate value
									Parityoption: NO_PARITY, EVEN_PARITY, ODD_PARITY, UART_BIT9_ENABLE	
									Rxinttriggerlevel; UART_TRIGGER_LEVEL_1_BYTE , UART_TRIGGER_LEVEL_4_BYTES , UART_TRIGGER_LEVEL_8_BYTES,UART_TRIGGER_LEVEL_18_BYTES  
Return Value	No
Condition	No
Function called	-

*****************************************************************************/
void UART_Open(UART0_Type *uart, uint32_t baudrate, uint8_t parityoption, uint8_t rxinttriggerlevel)
{
	uint32_t temp;
	//Init UART
  switch  ((uint32_t)uart)
	{
		case (uint32_t)UART0:
			//disable UART IRQ during setup
			NVIC_DisableIRQ(UART0_IRQn);
			//Enable UART clock
			SYSCON->SYSAHBCLKCTRL_b.UART0_CLK=1;	//enable UART0 PCLK
			//reset UART
			SYSCON->PRESETCTRL_b.UART0_RST_N=0;
			SYSCON->PRESETCTRL_b.UART0_RST_N=1;
			break;
		case (uint32_t)UART1:
			//disable UART IRQ during setup
			NVIC_DisableIRQ(UART1_IRQn);
			//Enable UART clock
			SYSCON->SYSAHBCLKCTRL_b.UART1_CLK=1;	//enable UART1 PCLK
			//reset UART
			SYSCON->PRESETCTRL_b.UART1_RST_N=0;
			SYSCON->PRESETCTRL_b.UART1_RST_N=1;		
			break;
		case (uint32_t)UART2:
		//disable UART IRQ during setup
		NVIC_DisableIRQ(UART2_IRQn);
			//Enable UART clock
			SYSCON->SYSAHBCLKCTRL_b.UART2_CLK=1;	//enable UART2 PCLK
			//reset UART
			SYSCON->PRESETCTRL_b.UART2_RST_N=0;
			SYSCON->PRESETCTRL_b.UART2_RST_N=1;				
			break;
		case (uint32_t)UART3:
		//disable UART IRQ during setup
		NVIC_DisableIRQ(UART3_IRQn);
			//Enable UART clock
			SYSCON->SYSAHBCLKCTRL_b.UART3_CLK=1;	//enable UART3 PCLK
			//reset UART
			SYSCON->PRESETCTRL_b.UART3_RST_N=0;
			SYSCON->PRESETCTRL_b.UART3_RST_N=1;
			break;

		default:
			return;
	}
	//date length
	uart->LCR_b.WLS=3; //8 bits
	
  //set up baudrate
	temp=SystemCoreClock/(baudrate);
	uart->DLR=temp>>4;
	uart->FRAC=temp&0xF;
	while(temp--);
	
	//set parity
	if (parityoption!=UART_NO_PARITY)
	{
		uart->LCR_b.PEN=1;
		uart->LCR_b.BIT9EN=0;
		if (parityoption==UART_ODD_PARITY)
			uart->LCR_b.PSEL=0;
		else if(parityoption==UART_EVEN_PARITY)
			uart->LCR_b.PSEL=1;
		else
			uart->LCR_b.BIT9EN=1;
	}else
		uart->LCR_b.PEN=0;
	
	//setup rx int trigger level
	uart->FCR_b.FIFOEN=1;
	uart->FCR_b.RXTL=rxinttriggerlevel;
	
	//clr FIFO
	uart->FCR_b.FIFOEN=1;
	uart->FCR_b.RXFIFORST=1;
	
  return;	
}
/*****************************************************************************
Function Name	UART_Close
Function Definition	void UART_Close(UART0_Type *uart);
Function Description	close UART
Input Parameters	*uart : pointer to UART device, UART0/UART1/UART2/UART3
Return Value	No
Condition	No
Function called	-

*****************************************************************************/
void UART_Close(UART0_Type *uart)
{
	 switch ((uint32_t)uart)
	{
		case (uint32_t)UART0:
			//disable UART0 IRQ during setup
			NVIC_DisableIRQ(UART0_IRQn);
			//Disable UART clock
			SYSCON->SYSAHBCLKCTRL_b.UART0_CLK=0;
		break;
		case (uint32_t)UART1:
			//disable UART0 IRQ during setup
			NVIC_DisableIRQ(UART1_IRQn);
			//Disable UART clock
			SYSCON->SYSAHBCLKCTRL_b.UART1_CLK=0;
		break;
		case (uint32_t)UART2:
			//disable UART0 IRQ during setup
			NVIC_DisableIRQ(UART1_IRQn);
			//Disable UART clock
			SYSCON->SYSAHBCLKCTRL_b.UART2_CLK=0;
		break;
		case (uint32_t)UART3:
			//disable UART0 IRQ during setup
			NVIC_DisableIRQ(UART1_IRQn);
			//Disable UART clock
			SYSCON->SYSAHBCLKCTRL_b.UART3_CLK=0;
		break;

		default:
			return;
	}

	//Disable UART int
	UART_DisableInt(uart);
	
	return;
}
/*****************************************************************************
Function Name	UART_ByteRead
Function Definition	Uint8_t UART_ByteRead(UART0_Type *uart, uint8_t *data);
Function Description	Read one byte from UART
Input Parameters	*uart : pointer to UART device, UART0/UART1/UART2/UART3
*data: if RX FIFO is not empty, return value
Return Value	If read success, return 0; otherwise return 1.
Condition	No
Function called	-

*****************************************************************************/
uint8_t UART_ByteRead(UART0_Type *uart, uint8_t *data)
{
	if (uart->LSR_b.RDR)
	{
		*data=uart->RBR;
		return 0;
	}else
		return 1;
}
/*****************************************************************************
Function Name	UART_Read
Function Definition	Uint8_t UART_Read(UART0_Type *uart, uint8_t * rxbuf, uint8_t *readbytes);
Function Description	Read data bytes from UART
Input Parameters	*uart : pointer to UART device, UART0/UART1/UART2/UART3
*rxbuf: data buffer used to store data from UART
*readbytes: number of read data in byte. return no of bytes got.
Return Value	No
Condition	No
Function called	-

*****************************************************************************/
void UART_Read(UART0_Type *uart, uint8_t * rxbuf, uint8_t *readbytes)
{
	uint8_t temp=0;
	//get all data
	while ((uart->LSR_b.RDR)&&((*readbytes)--))
	{
		*rxbuf++=uart->RBR;
		temp++;
	}
	//return number of read
	*readbytes=temp;
	return;
}
/*****************************************************************************
Function Name	UART_ByteWrite
Function Definition	Uint8_t UART_ByteWrite(UART0_Type *uart, uint8_t data);
Function Description	Write one byte to UART
Input Parameters	*uart : pointer to UART device, UART0/UART1/UART2/UART3
Data: data write to TX FIFO of UART
Return Value	If write success, return 0; otherwise return 1.
Condition	No
Function called	-

*****************************************************************************/
uint8_t UART_ByteWrite(UART0_Type *uart, uint8_t data)
{
	if (!(uart->LSR_b.THRE))
		return 1;
	
	uart->THR=data;
	return 0;
}
/*****************************************************************************
Function Name	UART_Write
Function Definition	Uint8_t UART_Write(UART0_Type *uart, uint8_t * txbuf, uint8_t writebytes);
Function Description	Write bytes to UART FIFO
Input Parameters	*uart : pointer to UART device, UART0/UART1/UART2/UART3
*txbuf: data buffer to UART
*writebytes: number of read data in byte. Maxum is 16. if TX FIFO is not empty, function return fail.
Return Value	If write success, return 0; otherwise return 1.
Condition	No
Function called	-

*****************************************************************************/
uint8_t  UART_Write(UART0_Type *uart, uint8_t * txbuf, uint8_t writebytes)
{
	if ((!(uart->LSR_b.THRE))||(writebytes>8))
		return 1;
	while (writebytes--)
	{
		uart->THR=*txbuf++;
	}
	return 0;
}	

/*****************************************************************************
Function Name	UART_Send
Function Definition	void UART_Send(UART0_Type *uart, uint8_t * txbuf, uint32_t sendbytes);
Function Description	Send bytes data via UART 
Input Parameters	*uart : pointer to UART device, UART0/UART1/UART2/UART3
*txbuf: data buffer to UART
sendbytes: number of data in byte to be sent 
Return Value	No
Condition	No
Function called	-

*****************************************************************************/
void UART_Send(UART0_Type *uart, uint8_t * txbuf, uint32_t sendbytes)
{
	while (sendbytes--)
	{
		while (!(uart->LSR_b.THRE));
		uart->THR=*txbuf++;
	}
	return;
}	
/*****************************************************************************
Function Name	UART_PutString
Function Definition	void UART_PutString (UART0_Type *uart, uint8_t * str);
Function Description	Send data string via UART 
Input Parameters	*uart : pointer to UART device, UART0/UART1/UART2/UART3
*str: data string 
Return Value	No
Condition	No
Function called	-

*****************************************************************************/
void UART_PutString (UART0_Type *uart, uint8_t * str)
{
	while (!(* str=='\0'))
	{
		while (!(uart->LSR_b.THRE));
		uart->THR=*str++;
	}
	return;
}
/*****************************************************************************
Function Name	UART_PutHex
Function Definition	void UART_PutHex (UART0_Type *uart, uint32_t data);
Function Description	Send data in hex format via UART 
Input Parameters	*uart : pointer to UART device, UART0/UART1/UART2/UART3
data: data to send 
Return Value	No
Condition	No
Function called	-

*****************************************************************************/
void UART_PutHex (UART0_Type *uart, uint32_t data)
{
	uint8_t hex;
	uint8_t len=7;
	do
	{
		hex=(data & 0xF0000000)>>28;
		if (hex>9)
			hex=hex+'A'-10;
		else
			hex+='0';
		while (!(uart->LSR_b.THRE));
		uart->THR=hex;
		data=data<<4;
	}while (len--);
	return;
}	
/*****************************************************************************
Function Name	UART_EnableInt
Function Definition	void UART_EnableInt(UART0_Type *uart, uint32_t intcon);
Function Description	Set UART interrupt type 
Input Parameters	*uart : pointer to UART device, UART0/UART1/UART2/UART3
intcon: interrupt type combination: UART_RX_INT,UART_TX_INT,UART_RX_LINE_INT,UART_MODEM_INT,UART_XOFF_INT,UART_RTS_INT,UART_CTS_INT
Return Value	No
Condition	No
Function called	-

*****************************************************************************/
void UART_EnableInt(UART0_Type *uart, uint32_t intcon)
{
	uart->IER |= intcon;
	return;
}
/*****************************************************************************
Function Name	UART_DisableInt
Function Definition	void UART_DisableInt(UART0_Type *uart);
Function Description	Disable UART interrupt 
Input Parameters	*uart : pointer to UART device, UART0/UART1/UART2/UART3
Return Value	No
Condition	No
Function called	-

*****************************************************************************/
void UART_DisableInt(UART0_Type *uart)
{
	uart->IER &= 0xFFFFFF00;
	return;
}


/*****************************************************************************
Function Name	UART_ClearFIFO
Function Definition	void UART_ClearFIFO(UART0_Type *uart,);
Function Description	Clear UART FIFO
Input Parameters	*uart : pointer to UART device, UART0/UART1/UART2/UART3
Return Value	No
Condition	No
Function called	-

*****************************************************************************/
void UART_ClearFIFO(UART0_Type *uart)
{
	uart->FCR_b.RXFIFORST=1;
	uart->FCR_b.TXFIFORST=1;
	return ;
}
void UART_EnableIrDA(UART0_Type *uart)
{
	uart->EFR_b.MEEN=1;
	uart->MCR_b.IREN=1;
}
void UART_DisableIrDA(UART0_Type *uart)
{
	uart->MCR_b.IREN=0;
}
/******************************************************************************
**                            End Of File
******************************************************************************/
